{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "initial_id",
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    ""
   ]
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 综合案例\n",
    "\n",
    "## 1、RAG结合大模型的小例子\n",
    "\n",
    "第1种情况：不使用RAG"
   ],
   "id": "a08940ff2c3f2c89"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:28:29.442091Z",
     "start_time": "2025-08-06T07:28:16.772593Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "import os\n",
    "import dotenv\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv(\"OPENAI_API_KEY1\")\n",
    "os.environ['OPENAI_BASE_URL'] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "# 创建大模型实例\n",
    "llm = ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "\n",
    "# 调用\n",
    "response = llm.invoke(\"北京有什么著名的建筑？\")\n",
    "print(response.content)"
   ],
   "id": "d5bb3d0c5a1ce752",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京作为中国的首都，拥有许多著名的建筑。以下是一些代表性的建筑：\n",
      "\n",
      "1. **故宫**：明清两代的皇宫，是中国古代宫殿建筑的精华，现为故宫博物院。\n",
      "2. **天安门广场**：世界上最大的城市广场，广场中央有人民英雄纪念碑和毛主席纪念堂。\n",
      "3. **天坛**：明清时期皇帝祭天的场所，以其精美的建筑和独特的设计著称。\n",
      "4. **颐和园**：中国现存最大的皇家园林，以湖泊、山丘和古典建筑群著称。\n",
      "5. **长城**：不仅是历史遗迹，也是一项了不起的建筑工程，特别是八达岭和慕田峪段吸引众多游客。\n",
      "6. **国家大剧院**：现代建筑的代表作，其独特的蛋形外观和周围的水景相得益彰。\n",
      "7. **鸟巢（国家体育场）**：2008年北京奥运会的主场馆，以其独特的外观和创新的结构设计闻名。\n",
      "8. **水立方（国家游泳中心）**：奥运会游泳比赛的场地，外立面仿佛由水泡构成，设计独特。\n",
      "9. **中央电视塔**：北京的标志性建筑之一，提供观景和广播功能。\n",
      "10. **798艺术区**：由原工厂改建而成的艺术区，集中了许多现代艺术展览和创意产业。\n",
      "\n",
      "这些建筑不仅展示了北京深厚的历史文化背景，也体现了现代建筑的创新与发展。\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "第2种情况：使用RAG",
   "id": "83673b915684818"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:31:12.448965Z",
     "start_time": "2025-08-06T07:31:04.972213Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 1. 导入所有需要的包\n",
    "from langchain.prompts import PromptTemplate\n",
    "from langchain_openai import ChatOpenAI,OpenAIEmbeddings\n",
    "from langchain_community.document_loaders import TextLoader\n",
    "from langchain.text_splitter import CharacterTextSplitter\n",
    "from langchain_community.vectorstores import FAISS\n",
    "import os\n",
    "import dotenv\n",
    "\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "# 2. 创建自定义提示词模板\n",
    "prompt_template = \"\"\"请使用以下提供的文本内容来回答问题。仅使用提供的文本信息，如果文本中没有相关信息，请回答\"抱歉，提供的文本中没有这个信息\"。\n",
    "\n",
    "文本内容：\n",
    "{context}\n",
    "\n",
    "问题：{question}\n",
    "\n",
    "回答：\n",
    "\"\n",
    "\"\"\"\n",
    "\n",
    "prompt = PromptTemplate.from_template(prompt_template)\n",
    "\n",
    "# 3. 初始化模型\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv(\"OPENAI_API_KEY1\")\n",
    "os.environ['OPENAI_BASE_URL'] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "llm = ChatOpenAI(\n",
    "    model=\"gpt-4o-mini\",\n",
    "    temperature=0\n",
    ")\n",
    "\n",
    "embeddings = OpenAIEmbeddings(model=\"text-embedding-3-large\")\n",
    "\n",
    "# 4. 加载文档\n",
    "loader = TextLoader(\"./asset/load/10-test_doc.txt\", encoding='utf-8')\n",
    "documents = loader.load()\n",
    "\n",
    "# 5. 分割文档\n",
    "text_splitter = CharacterTextSplitter(\n",
    "    chunk_size=1000,\n",
    "    chunk_overlap=0,\n",
    "    length_function=len\n",
    ")\n",
    "texts = text_splitter.split_documents(documents)\n",
    "\n",
    "print(f\"文档个数:{len(texts)}\")\n",
    "\n",
    "# 6. 创建向量存储\n",
    "vectorstore = FAISS.from_documents(\n",
    "    documents=texts,\n",
    "    embedding=embeddings\n",
    ")\n",
    "\n",
    "# 7.获取检索器\n",
    "retriever = vectorstore.as_retriever()\n",
    "\n",
    "docs = retriever.invoke(\"北京有什么著名的建筑？\")\n",
    "\n",
    "# 8. 创建Runnable链\n",
    "chain = prompt | llm\n",
    "\n",
    "# 9. 提问\n",
    "result = chain.invoke(input={\"question\":\"北京有什么著名的建筑？\",\"context\":docs})\n",
    "print(\"\\n回答:\", result.content)"
   ],
   "id": "84255919a5993dec",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "文档个数:1\n",
      "\n",
      "回答: 北京有以下著名的建筑：\n",
      "\n",
      "1. 故宫 - 明清两代的皇家宫殿，世界上现存规模最大、保存最完整的木质结构古建筑群之一。\n",
      "2. 天安门 - 北京的标志性建筑之一，天安门广场是世界上最大的城市广场。\n",
      "3. 颐和园 - 清朝时期的皇家园林，融合了江南园林的设计风格。\n",
      "4. 天坛 - 明清两代皇帝祭天、祈谷的场所，具有深厚的文化内涵。\n",
      "5. 长城（八达岭段） - 最著名的北京段，被誉为\"世界第八大奇迹\"。\n",
      "6. 国家体育场（鸟巢） - 2008年奥运会主体育场，以独特的钢结构设计著称。\n",
      "7. 中央电视台总部大楼 - 俗称\"大裤衩\"，现代北京最具争议的建筑之一。\n",
      "8. 国家大剧院 - 因其蛋壳造型被称为\"巨蛋\"，是世界最大的穹顶建筑之一。\n",
      "9. 北京大兴国际机场 - 超大型国际航空枢纽，被誉为\"新世界七大奇迹\"之一。\n",
      "10. 鼓楼和钟楼 - 古代中国的报时中心，展现了古代的计时智慧。\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 2、项目：智能对话助手\n",
    "\n",
    "1、提示词模板：ChatPromptTemplate、PromptTemplate等\n",
    "\n",
    "2、大语言模型的调用：ChatOpenAI() 、 OpenAI()\n",
    "\n",
    "3、(熟悉)输出解析器：JSONOutputParser、StrOutputParser\n",
    "\n",
    "4、Chain的使用：LLMChain、SequentialChain; | 、create_sql_query_chain\n",
    "\n",
    "5、关于模型调用前，给模型提供上下文信息：memory：ChatMessageHistory、ConversationBufferMemory\n",
    "\n",
    "6、工具的创建；工具的使用，给Agent\n",
    "\n",
    "7、Agent的使用：Agent ---> AgentExecutor   ---> LangGraph\n",
    "\n",
    "传统的方式：initialize_agent(llm = llm,agent=AgentType.XXX,tools=tools)\n",
    "\n",
    "通用的方式：create_xxx_agent(llm=llm,tools=tools,prompt=prompt)\n",
    "             AgentExecutor(agent=agent,toos=tools)\n",
    "\n",
    "8、数据的本地存储（使用向量数据库）：RAG\n",
    "   具体的流程：XxxLoader --> list[Document] --> XxxSplitter ---> list[Document] -->\n",
    "             OpenAIEmbeddings() ---> FAISS/Chroma  ---> Retriever\n",
    "\n",
    "\n",
    "## 步骤1：定义工具\n"
   ],
   "id": "96dd0a5755b1d63f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:48:26.502914Z",
     "start_time": "2025-08-06T07:48:23.783087Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import os\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "\n",
    "# 定义 AVILY_KEY 密钥\n",
    "os.environ[\"TAVILY_API_KEY\"] = \"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\"\n",
    "# 查询 Tavily 搜索 API\n",
    "search = TavilySearchResults(max_results=1)\n",
    "# 执行查询\n",
    "res = search.invoke(\"今天上海天气怎么样\")\n",
    "print(res)"
   ],
   "id": "9c157ecce8c322de",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'title': '中国气象局-天气预报-城市预报- 上海', 'url': 'https://weather.cma.cn/web/weather/58367.html', 'content': '|  |  |  |  |  |  |  |  |  |\\n| --- | --- | --- | --- | --- | --- | --- | --- | --- |\\n| æ\\x97¶é\\x97´ | 08:00 | 11:00 | 14:00 | 17:00 | 20:00 | 23:00 | 02:00 | 05:00 |\\n| å¤©æ°\\x94 |  |  |  |  |  |  |  |  |\\n| æ°\\x94æ¸© | 25.9â\\x84\\x83 | 30.8â\\x84\\x83 | 31.5â\\x84\\x83 | 30.3â\\x84\\x83 | 28.1â\\x84\\x83 | 25.2â\\x84\\x83 | 23.7â\\x84\\x83 | 24.1â\\x84\\x83 |\\n| é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ |\\n| é£\\x8eé\\x80\\x9f | 7.9m/s | 7.9m/s | 7.7m/s | 7.5m/s | 7.5m/s | 7.9m/s | 7.7m/s | 7.5m/s | [...] |  |  |  |  |  |  |  |  |  |\\n| --- | --- | --- | --- | --- | --- | --- | --- | --- |\\n| æ\\x97¶é\\x97´ | 14:00 | 17:00 | 20:00 | 23:00 | 02:00 | 05:00 | 08:00 | 11:00 |\\n| å¤©æ°\\x94 |  |  |  |  |  |  |  |  |\\n| æ°\\x94æ¸© | 32.3â\\x84\\x83 | 28.5â\\x84\\x83 | 25.9â\\x84\\x83 | 23.7â\\x84\\x83 | 23â\\x84\\x83 | 22.6â\\x84\\x83 | 25.9â\\x84\\x83 | 30.8â\\x84\\x83 |\\n| é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ | æ\\x97 é\\x99\\x8dæ°´ |\\n| é£\\x8eé\\x80\\x9f | 7.9m/s | 7.4m/s | 7.4m/s | 7.8m/s | 7.7m/s | 7.5m/s | 7.9m/s | 7.9m/s | [...] |  |  |  |  |  |  |  |  |  |\\n| --- | --- | --- | --- | --- | --- | --- | --- | --- |\\n| æ\\x97¶é\\x97´ | 08:00 | 11:00 | 14:00 | 17:00 | 20:00 | 23:00 | 02:00 | 05:00 |\\n| å¤©æ°\\x94 |  |  |  |  |  |  |  |  |\\n| æ°\\x94æ¸© | 23.3â\\x84\\x83 | 25â\\x84\\x83 | 26.2â\\x84\\x83 | 25.8â\\x84\\x83 | 25.4â\\x84\\x83 | 24.4â\\x84\\x83 | 23.8â\\x84\\x83 | 22.6â\\x84\\x83 |\\n| é\\x99\\x8dæ°´ | 2.3mm | 2.3mm | 2.3mm | 2.3mm | 2.3mm | æ\\x97 é\\x99\\x8dæ°´ | 5.2mm | æ\\x97 é\\x99\\x8dæ°´ |\\n| é£\\x8eé\\x80\\x9f | 3.3m/s | 3.3m/s | 3.3m/s | 3.3m/s | 3.3m/s | 3m/s | 2.9m/s | 3m/s |', 'score': 0.7251239}]\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 步骤2：Retriever",
   "id": "86ab566305915f7f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:50:08.545290Z",
     "start_time": "2025-08-06T07:50:03.542082Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_community.document_loaders import WebBaseLoader\n",
    "from langchain_community.vectorstores import FAISS\n",
    "from langchain_openai import OpenAIEmbeddings\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "import os\n",
    "import dotenv\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "# 1. 提供一个大模型\n",
    "os.environ['OPENAI_API_KEY'] = os.getenv(\"OPENAI_API_KEY1\")\n",
    "os.environ['OPENAI_BASE_URL'] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "\n",
    "embedding_model = OpenAIEmbeddings()\n",
    "\n",
    "# 2.加载HTML内容为一个文档对象\n",
    "loader = WebBaseLoader(\"https://zh.wikipedia.org/wiki/%E7%8C%AB\")\n",
    "docs = loader.load()\n",
    "#print(docs)\n",
    "\n",
    "# 3.分割文档\n",
    "documents = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=1000,\n",
    "    chunk_overlap=200\n",
    ").split_documents(docs)\n",
    "\n",
    "# 4.向量化 得到向量数据库对象\n",
    "vector = FAISS.from_documents(documents, embedding_model)\n",
    "\n",
    "# 5.创建检索器\n",
    "retriever = vector.as_retriever()\n",
    "\n",
    "# 测试检索结果\n",
    "#print(retriever.invoke(\"猫的特征\")[0])"
   ],
   "id": "c0ca38f28fc0aa25",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "USER_AGENT environment variable not set, consider setting it to identify your requests.\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 步骤3：创建工具、工具集\n",
   "id": "7802785319352977"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:52:11.644131Z",
     "start_time": "2025-08-06T07:52:11.614204Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.tools.retriever import create_retriever_tool\n",
    "\n",
    "# 创建一个工具来检索文档\n",
    "retriever_tool = create_retriever_tool(\n",
    "    retriever=retriever,\n",
    "    name=\"wiki_search\",\n",
    "    description=\"搜索维基百科\",\n",
    ")\n",
    "\n",
    "tools = [search, retriever_tool]"
   ],
   "id": "797524cfd65ddcb9",
   "outputs": [],
   "execution_count": 6
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 步骤4：语言模型调用工具",
   "id": "8049639800992a19"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:52:15.134444Z",
     "start_time": "2025-08-06T07:52:13.911388Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.messages import HumanMessage\n",
    "\n",
    "# 获取大模型\n",
    "model = ChatOpenAI(model=\"gpt-4o-mini\")\n",
    "\n",
    "# 模型绑定工具\n",
    "# model_with_tools = model.bind_tools(tools)\n",
    "#\n",
    "# # 根据输入自动调用工具\n",
    "# response = model_with_tools.invoke([HumanMessage(content=\"今天上海天气怎么样\")])\n",
    "# print(f\"ContentString: {response.content}\")\n",
    "# print(f\"ToolCalls: {response.tool_calls}\")\n"
   ],
   "id": "14bef76aff481d8d",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ContentString: \n",
      "ToolCalls: [{'name': 'tavily_search_results_json', 'args': {'query': '今天 上海 天气'}, 'id': 'call_zeg0TvoRlMGKsoTHBkEQHVXf', 'type': 'tool_call'}]\n"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 步骤5：创建Agent程序(使用通用方式)",
   "id": "9c615f0444aa3fd"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:54:18.561544Z",
     "start_time": "2025-08-06T07:54:17.524511Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain import hub\n",
    "prompt = hub.pull(\"hwchase17/openai-functions-agent\")\n",
    "\n",
    "prompt.messages"
   ],
   "id": "defb077b98435404",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\developTools\\miniconda3\\envs\\pyth310\\lib\\site-packages\\langsmith\\client.py:272: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='You are a helpful assistant'), additional_kwargs={}),\n",
       " MessagesPlaceholder(variable_name='chat_history', optional=True),\n",
       " HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, template='{input}'), additional_kwargs={}),\n",
       " MessagesPlaceholder(variable_name='agent_scratchpad')]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 8
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:54:51.094278Z",
     "start_time": "2025-08-06T07:54:50.744323Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.agents import create_tool_calling_agent\n",
    "from langchain.agents import AgentExecutor\n",
    "# 创建Agent对象\n",
    "agent = create_tool_calling_agent(model, tools, prompt)\n",
    "\n",
    "# 创建AgentExecutor对象\n",
    "agent_executor = AgentExecutor(agent=agent, tools=tools,verbose=True)"
   ],
   "id": "5aca524c2015aa0e",
   "outputs": [],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 步骤6：运行Agent\n",
   "id": "100f10767ad7ad2f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:55:21.734309Z",
     "start_time": "2025-08-06T07:55:14.458510Z"
    }
   },
   "cell_type": "code",
   "source": "print(agent_executor.invoke({\"input\": \"猫的特征\"}))",
   "id": "5d96edc98031636e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m\n",
      "Invoking: `wiki_search` with `{'query': '猫'}`\n",
      "\n",
      "\n",
      "\u001B[0m\u001B[33;1m\u001B[1;3m一隻貓正在吃碗中的乾猫粮\n",
      "行為[编辑]\n",
      "一只望向窗外的猫\n",
      "排泄[编辑]\n",
      "貓在排泄後會掩埋其排泄物。在中国形容人做事马虎的谚语“猫儿埋狗屎”。這是一種為了掩藏自己氣息的做法，因為在野外貓並不是很高級的獵食者，需要把自己藏起來不被天敵發現。但是一些家貓生活在比較安全的環境裡，會漸漸放棄掩埋自己的排泄物，這種變化有可能是後天形成的。\n",
      "\n",
      "睡眠[编辑]\n",
      "貓為補充精力，睡眠時間比較其它動物長久。每日睡眠時間在12至16小時間，平均在13至14小時，部分更會睡眠20小時，惟只有30%的睡眠為酣睡期，其餘睡覺時間皆為非酣睡期，容易驚醒。在英文中，“cat nap”（打盹）即為指能夠像貓一樣快速入睡。牠們常在晚間活動，但並不表示他們是夜行性動物。\n",
      "\n",
      "發聲[编辑]\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "喵\n",
      "\n",
      "\n",
      "播放此文件有问题？请参见媒體幫助。\n",
      "\n",
      "参见：喵\n",
      "各個語言對貓叫聲（ⓘ）的擬聲詞，在漢語為喵（miāo）、韓語為yang-yang（양양）[來源請求]、日語為nyaa（にゃあ）、美式英語為meow、英式英語為miaow、法語為miaou，以及其他不同的語言拼法。貓叫聲有著其意味深長的意涵，貓也會發出使人舒服[來源請求]，開心的呜呜聲，和低聲嘶吼，貓甚至可以同時喵喵、貓貓叫或發出呜呜聲，儘管這很少見。有時貓也會嗥叫或鳴叫。除了喵喵叫以外，貓還會發出咕嚕聲（ⓘ），推測可能是延續小貓時想喝奶時所發出的聲音，不確定如何發出這種特有的咕嚕聲，可能從喉嚨裡、聲帶附近的薄膜振動所產生，成年貓發出咕嚕聲通常表示友好、滿意、放鬆，但生病或煩躁的貓偶爾也會發出咕嚕聲。猫在遇到敌人时，也会发出像蛇一样的嘶嘶声，用来震慑敌人。另外貓發現到遠方的鳥類時，會非常專注的凝視並發出『啊啊啊啊』、『嘎嘎嘎嘎』的高頻叫聲，英语中稱為貓鳴（cat chirping）或貓啁啾（cat chattering），飼養在室內或大樓裡的貓尤常出現這種狀況，對著窗外的鳥發出這種叫聲。某些貓先天無法發聲，稱為無聲貓，亦有聲帶被割而無法發聲者。\n",
      "\n",
      "遊戲[编辑]\n",
      "幼貓常會藉與其他貓遊戲以訓練自己捕捉獵物，由人類豢養的貓大多會用人造的逗貓棒予貓玩。就室內貓而言，遊戲為良好運動，亦能夠增進與同伴的情誼。\n",
      "\n",
      "猫 - 维基百科，自由的百科全书\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "跳转到内容\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "主菜单\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "主菜单\n",
      "移至侧栏\n",
      "隐藏\n",
      "\n",
      "\n",
      "\n",
      "\t\t导航\n",
      "\t\n",
      "\n",
      "\n",
      "首页分类索引特色内容新闻动态最近更改随机条目\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\t\t帮助\n",
      "\t\n",
      "\n",
      "\n",
      "帮助维基社群方针与指引互助客栈知识问答字词转换IRC即时聊天联络我们关于维基百科特殊页面\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "搜索\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "搜索\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "外观\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "资助维基百科\n",
      "\n",
      "创建账号\n",
      "\n",
      "登录\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "个人工具\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "资助维基百科 创建账号 登录\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "目录\n",
      "移至侧栏\n",
      "隐藏\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "序言\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "1\n",
      "分類學\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "2\n",
      "称呼\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "开关称呼子章节\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "2.1\n",
      "西方語言\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "3\n",
      "演化歷史\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "开关演化歷史子章节\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "3.1\n",
      "古代貓科動物\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "3.2\n",
      "演化近親\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "3.3\n",
      "馴化\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "3.4\n",
      "文獻記載\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "4\n",
      "生活史\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "开关生活史子章节\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "4.1\n",
      "繁殖\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "4.2\n",
      "生產\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "4.3\n",
      "幼貓期\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "4.4\n",
      "成貓期\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "5\n",
      "食物和營養\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6\n",
      "行為\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "开关行為子章节\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.1\n",
      "排泄\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.2\n",
      "睡眠\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.3\n",
      "發聲\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.4\n",
      "遊戲\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.5\n",
      "肢體語言\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.6\n",
      "地域性與外出\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.7\n",
      "空间\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "6.8\n",
      "與狗的關係\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7\n",
      "生理與身體部位\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "开关生理與身體部位子章节\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.1\n",
      "消化系統\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.2\n",
      "循環系統\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.3\n",
      "呼吸系統\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.4\n",
      "生殖系統\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.5\n",
      "中樞神經系統\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.6\n",
      "骨骼\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.7\n",
      "貓爪\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.8\n",
      "感官\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.8.1\n",
      "視覺\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.8.2\n",
      "聽覺\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "7.8.3\n",
      "嗅覺\n",
      "\n",
      "各種不同的貓\n",
      "\n",
      "\n",
      "保护状况\n",
      "\n",
      "\n",
      "驯养\n",
      "\n",
      "\n",
      "科学分类 \n",
      "\n",
      "\n",
      "界：\n",
      "\n",
      "动物界 Animalia\n",
      "\n",
      "\n",
      "门：\n",
      "\n",
      "脊索动物门 Chordata\n",
      "\n",
      "\n",
      "纲：\n",
      "\n",
      "哺乳纲 Mammalia\n",
      "\n",
      "\n",
      "目：\n",
      "\n",
      "食肉目 Carnivora\n",
      "\n",
      "\n",
      "科：\n",
      "\n",
      "猫科 Felidae\n",
      "\n",
      "\n",
      "属：\n",
      "\n",
      "貓屬 Felis\n",
      "\n",
      "\n",
      "种：\n",
      "\n",
      "貓 F. catus\n",
      "\n",
      "\n",
      "二名法\n",
      "\n",
      "\n",
      "Felis catusLinnaeus, 1758\n",
      "\n",
      "\n",
      "異名\n",
      "\n",
      "\n",
      "\n",
      "Felis silvestris catus (Linnaeus, 1758)\n",
      "Felis catus catus (Linnaeus, 1758)\n",
      "Felis catus domesticus Erxleben, 1777\n",
      "Felis angorensis Gmelin, 1788\n",
      "Felis vulgaris Fischer, 1829\n",
      "\n",
      "\n",
      "一隻英国短毛貓\n",
      "貓（英語：cat）通常指家貓（學名：Felis catus[1][2][3]，英語：domestic/house cat），是一种家养[4]小型食肉哺乳动物，属小型貓科動物。根據遺傳學及考古學分析，人類養貓的紀錄可追溯至10,000年前的新月沃土地區。古埃及人飼養貓以防止老鼠偷食穀物的紀錄可追溯至公元前1000年前[5]。\n",
      "現在，貓成為世界上最為廣泛的寵物之一，飼養率僅次於狗，可以治療低落的心情與提供情緒價值等[6]。長期室內飼养的貓平均健康則較長，壽命為12年以上，歷史上最長壽的貓則達38歲[7]，也因此在部分城市中選擇養貓的家戶已經超過了狗[8]。但同時貓是一種掠食動物，大量的貓咪因為弃养接觸外部環境，除了在惡劣的衛生引發疫情散佈，也會造成城市管理問題[9]。其次，这些猫威脅了鳥類、齧齒類的生存。[10]\n",
      "\n",
      "称呼[编辑]\n",
      "傳統字「貓」屬於漢字中的形聲字，「豸」表意、「苗」標音。在《說文解字》裡，寫作「」[21]，與傳統楷書的「貓」字一脈相承。「豸」後世通常認為是一種中國古代傳說中的獸類，以該字為意的通常為四足食肉哺乳動物，但是現代文字學家馬敘倫[22]以及馬如森[23]考證「豸」即為「貓」的象形初文。後加注聲符「苗」[22]（武瀌切，中古音：明母次濁平聲效攝宵目三等開口，中古擬音：mieu，現代普通话拼音：miáo），是因為漢語「貓」（武瀌切，中古音：明母次濁平聲效攝宵目三等開口，中古擬音：mieu，現代普通话拼音：māo）和「苗」讀音相近，而漢語之所以以「喵」相近的讀音命名貓是因為貓叫聲像「苗」，属于擬聲詞。之所以「豸」後世讀如池爾切（中古音：澄母全濁上聲止攝紙目三等開口，中古擬音：driex，現代普通话拼音：zhì），可能因為「豸」加了聲符「苗」寫作「貓」所以「豸」空了出來被假借用作「廌」（池爾切，中古音：澄母全濁上聲止攝紙目三等開口，中古擬音：driex，現代普通话拼音：zhì）。\n",
      "在唐代，出現了将「貓」寫作「猫」的俗字写法，例如《唐中書侍郎同中書門下平童事常山縣開國子贈太傅博陵崔公墓誌》一书中，将「豸」简寫为「犭」[24]。這個俗字在当时并未成為主流，直到現代日本新字體和中國大陸《第一批异体字整理表》[註 1]采用这个字取代了「貓」。\n",
      "貓字一般指家猫，但也可指野貓，家貓在現今社會中，又常稱為「貓咪」，古時野貓也稱「貍」，拼音：lí，注音：ㄌㄧˊ」或貍奴[25]，今有雙音節詞貍貓。在川滇渝黔湘等部分西南地区叫做“嘛咪咪”。\n",
      "\n",
      "西方語言[编辑]\n",
      "古希臘文Kattos及拉丁文Catus是現代大部分西方語言中「貓」字的詞源，如英文的cat、法語的chat、意大利文的gatto等。这些词通常用以指代家貓（學名：F. silvestris catus）或其近緣動物如斑貓（學名：F. silvestris）。\n",
      "西方語言對於貓有很多不同的暱稱，例如在英語中，幼貓可以叫作kitten，血統的區別亦然，如非純種的貓在英國被稱為moggy（也写作moggie）；在北美可以被稱alley cat，即使它們實際上並不是流浪貓（在英語中，alley意為巷）。\u001B[0m\u001B[32;1m\u001B[1;3m猫（学名：Felis catus）是一种小型的肉食性哺乳动物，属于猫科，通常以其灵活的身体和敏锐的感官特征而受到喜爱。以下是猫的一些主要特征：\n",
      "\n",
      "1. **身体特征**：\n",
      "   - 猫通常具有柔软而灵活的身体，敏捷的四肢和短尾巴，尾巴可以用来帮助保持平衡。\n",
      "   - 它们的爪子是可伸缩的，使得在捕猎和攀爬时更加灵活。\n",
      "\n",
      "2. **感官**：\n",
      "   - 猫的夜视能力很强，能在低光环境中看到东西。\n",
      "   - 其听觉非常敏锐，能够听到高频声波。\n",
      "   - 猫的嗅觉也很不错，帮助它们在环境中寻找食物和识别猎物。\n",
      "\n",
      "3. **行为特征**：\n",
      "   - 猫通常是独立的动物，但也能够和人类及其他动物建立良好的关系。\n",
      "   - 它们常通过发出不同的叫声（如“喵”）来表达需求和情感。\n",
      "   - 猫在狩猎时表现出强烈的猎捕本能，喜欢通过玩耍来训练这些技能。\n",
      "\n",
      "4. **生理特征**：\n",
      "   - 猫的睡眠时间较长，每天可以睡12至16小时，甚至有些猫会睡到20小时。\n",
      "   - 其排泄习惯是会掩埋排泄物，这是一种自然行为，以防捕食者发现它们的气味。\n",
      "\n",
      "5. **社交行为**：\n",
      "   - 猫的社交行为通常是通过肢体语言和声音传达的，它们用尾巴、耳朵和身体姿势来表达感受。\n",
      "   - 幼猫通过与其他猫的玩耍来学习捕猎技能。\n",
      "\n",
      "6. **繁殖**：\n",
      "   - 猫的繁殖能力很强，雌猫在发情过程中会吸引雄猫。\n",
      "\n",
      "总之，猫是一种灵活、多样化且智慧的动物，它们的特征使得它们能够在各种环境中生存，并且与人们建立紧密的关系。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '猫的特征', 'output': '猫（学名：Felis catus）是一种小型的肉食性哺乳动物，属于猫科，通常以其灵活的身体和敏锐的感官特征而受到喜爱。以下是猫的一些主要特征：\\n\\n1. **身体特征**：\\n   - 猫通常具有柔软而灵活的身体，敏捷的四肢和短尾巴，尾巴可以用来帮助保持平衡。\\n   - 它们的爪子是可伸缩的，使得在捕猎和攀爬时更加灵活。\\n\\n2. **感官**：\\n   - 猫的夜视能力很强，能在低光环境中看到东西。\\n   - 其听觉非常敏锐，能够听到高频声波。\\n   - 猫的嗅觉也很不错，帮助它们在环境中寻找食物和识别猎物。\\n\\n3. **行为特征**：\\n   - 猫通常是独立的动物，但也能够和人类及其他动物建立良好的关系。\\n   - 它们常通过发出不同的叫声（如“喵”）来表达需求和情感。\\n   - 猫在狩猎时表现出强烈的猎捕本能，喜欢通过玩耍来训练这些技能。\\n\\n4. **生理特征**：\\n   - 猫的睡眠时间较长，每天可以睡12至16小时，甚至有些猫会睡到20小时。\\n   - 其排泄习惯是会掩埋排泄物，这是一种自然行为，以防捕食者发现它们的气味。\\n\\n5. **社交行为**：\\n   - 猫的社交行为通常是通过肢体语言和声音传达的，它们用尾巴、耳朵和身体姿势来表达感受。\\n   - 幼猫通过与其他猫的玩耍来学习捕猎技能。\\n\\n6. **繁殖**：\\n   - 猫的繁殖能力很强，雌猫在发情过程中会吸引雄猫。\\n\\n总之，猫是一种灵活、多样化且智慧的动物，它们的特征使得它们能够在各种环境中生存，并且与人们建立紧密的关系。'}\n"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:56:08.372705Z",
     "start_time": "2025-08-06T07:55:58.672339Z"
    }
   },
   "cell_type": "code",
   "source": "print(agent_executor.invoke({\"input\": \"今天上海天气怎么样\"}))",
   "id": "b27f7f3ff663d4d4",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m\n",
      "Invoking: `tavily_search_results_json` with `{'query': '上海天气'}`\n",
      "\n",
      "\n",
      "\u001B[0m\u001B[36;1m\u001B[1;3m[{'title': '上海地理- 维基百科，自由的百科全书', 'url': 'https://zh.wikipedia.org/zh-hans/%E4%B8%8A%E6%B5%B7%E5%9C%B0%E7%90%86', 'content': '年平均气温：17.1°C。（市区17.5 °C）\\n   最冷月（1月）平均气温：4.9°C。（市区5.4°C）\\n   最热月（7月）平均气温：28.8°C。（市区29.1 °C）\\n   极端最低气温：-12.1°C（出现在1893年1月19日）。\\n   极端最高气温：40.9°C（出现在2017年7月21日以及2022年7月13日( [...] | 上海市气候数据（宝山区 \"宝山区 (上海市)\")），（1991-2020年平均，极值自1951年至今） |\\n| --- |\\n| 月份 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 | 全年 |\\n| 历史最高温 °C（°F） | 23.0 (73.4) | 27.0 (80.6) | 30.9 (87.6) | 34.3 (93.7) | 36.4 (97.5) | 37.5 (99.5) | 39.7 (103.5) | 40.0 (104.0) | 38.2 (100.8) | 36.7 (98.1) | 29.2 (84.6) | 24.4 (75.9) | 40.0 (104.0) | [...] | 上海市气候数据 (上海虹桥国际机场)， (2015-2024年平均, 极值自2013年至今) |\\n| --- |\\n| 月份 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 | 全年 |\\n| 历史最高温 °C（°F） | 24.0 (75.2) | 27.0 (80.6) | 32.0 (89.6) | 33.0 (91.4) | 37.0 (98.6) | 38.0 (100.4) | 42.0 (107.6) | 41.0 (105.8) | 38.0 (100.4) | 36.0 (96.8) | 30.0 (86.0) | 24.0 (75.2) | 42.0 (107.6) |', 'score': 0.79369855}]\u001B[0m\u001B[32;1m\u001B[1;3m\n",
      "Invoking: `tavily_search_results_json` with `{'query': '上海天气预报'}`\n",
      "\n",
      "\n",
      "\u001B[0m\u001B[36;1m\u001B[1;3m[{'title': '上海-天气预报 - 中央气象台', 'url': 'https://www.nmc.cn/publish/forecast/ASH/shanghai.html', 'content': '土壤水分监测\\n       农业干旱综合监测\\n       关键农时农事\\n       农业气象周报\\n       农业气象月报\\n       农业气象专报\\n       生态气象监测评估\\n       作物发育期监测\\n\\n   数值预报\\n\\n       CMA全球天气模式\\n       CMA全球集合模式\\n       CMA区域模式\\n       CMA区域集合模式\\n       CMA台风模式\\n       海浪模式\\n\\n1.    当前位置：首页\\n2.   上海市\\n3.   上海天气预报\\n\\n省份：城市：\\n\\n02:55更新\\n\\n日出04:50\\n\\n 上海 \\n\\n22.9℃\\n\\n日落18:55\\n\\n 降水量 \\n\\n0mm\\n\\n-\\n\\n-\\n\\n 相对湿度 \\n\\n65%\\n\\n 体感温度 \\n\\n25.4℃\\n\\n空气质量：优\\n\\n舒适度：温暖，较舒适\\n\\n 雷达图 \\n\\nImage 4\\n\\n24小时预报7天预报10天预报11-30天预报\\n\\n 发布时间：06-04 20:00 \\n\\n 06/04 \\n\\n周三 \\n\\n 21℃ \\n\\nImage 5\\n\\n 阴 \\n\\n 南风 \\n\\n 微风 \\n\\n 06/05 \\n\\n周四', 'score': 0.8215175}]\u001B[0m\u001B[32;1m\u001B[1;3m今天上海的天气情况如下：\n",
      "\n",
      "- 当前温度：**22.9℃**\n",
      "- 体感温度：**25.4℃**\n",
      "- 相对湿度：**65%**\n",
      "- 显示空气质量：**优**\n",
      "- 舒适度：**温暖，较舒适**\n",
      "- 预测降水量：**0mm**（预计不会下雨）\n",
      "\n",
      "日出时间为：**04:50**，日落时间为：**18:55**。\n",
      "\n",
      "总体来看，今天的天气非常适合外出活动。有关详细天气预报，请查看[中央气象台的详细信息](https://www.nmc.cn/publish/forecast/ASH/shanghai.html)。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '今天上海天气怎么样', 'output': '今天上海的天气情况如下：\\n\\n- 当前温度：**22.9℃**\\n- 体感温度：**25.4℃**\\n- 相对湿度：**65%**\\n- 显示空气质量：**优**\\n- 舒适度：**温暖，较舒适**\\n- 预测降水量：**0mm**（预计不会下雨）\\n\\n日出时间为：**04:50**，日落时间为：**18:55**。\\n\\n总体来看，今天的天气非常适合外出活动。有关详细天气预报，请查看[中央气象台的详细信息](https://www.nmc.cn/publish/forecast/ASH/shanghai.html)。'}\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 步骤7：添加记忆",
   "id": "17f879660e54d328"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:58:55.647513Z",
     "start_time": "2025-08-06T07:58:54.451830Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_community.chat_message_histories import ChatMessageHistory\n",
    "\n",
    "from langchain_core.chat_history import BaseChatMessageHistory\n",
    "\n",
    "from langchain_core.runnables.history import RunnableWithMessageHistory\n",
    "\n",
    "store = {}\n",
    "\n",
    "# 调取指定session_id对应的memory\n",
    "def get_session_history(session_id: str) -> BaseChatMessageHistory:\n",
    "\n",
    "    if session_id not in store:\n",
    "        store[session_id] = ChatMessageHistory()\n",
    "\n",
    "    return store[session_id]\n",
    "\n",
    "agent_with_chat_history = RunnableWithMessageHistory(\n",
    "    runnable=agent_executor,\n",
    "    get_session_history=get_session_history,\n",
    "    input_messages_key=\"input\",\n",
    "    history_messages_key=\"chat_history\",\n",
    ")\n",
    "\n",
    "response = agent_with_chat_history.invoke(\n",
    "    {\"input\": \"Hi，我的名字是Cyber\"},\n",
    "    config={\"configurable\": {\"session_id\": \"123\"}},\n",
    ")\n",
    "\n",
    "print(response)"
   ],
   "id": "872a217f2f9bab2b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m你好，Cyber！很高兴认识你！有什么我可以帮助你的吗？\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': 'Hi，我的名字是Cyber', 'chat_history': [], 'output': '你好，Cyber！很高兴认识你！有什么我可以帮助你的吗？'}\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:59:18.998749Z",
     "start_time": "2025-08-06T07:59:17.769864Z"
    }
   },
   "cell_type": "code",
   "source": [
    "response = agent_with_chat_history.invoke(\n",
    "    {\"input\": \"我的名字叫什么？\"},\n",
    "    config={\"configurable\": {\"session_id\": \"123\"}},\n",
    ")\n",
    "\n",
    "print(response)"
   ],
   "id": "c802b90a37299e7b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m你的名字是Cyber。请问你还有其他问题或需要帮助的吗？\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '我的名字叫什么？', 'chat_history': [HumanMessage(content='Hi，我的名字是Cyber', additional_kwargs={}, response_metadata={}), AIMessage(content='你好，Cyber！很高兴认识你！有什么我可以帮助你的吗？', additional_kwargs={}, response_metadata={})], 'output': '你的名字是Cyber。请问你还有其他问题或需要帮助的吗？'}\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-06T07:59:34.664975Z",
     "start_time": "2025-08-06T07:59:33.414720Z"
    }
   },
   "cell_type": "code",
   "source": [
    "response = agent_with_chat_history.invoke(\n",
    "    {\"input\": \"我的名字叫什么？\"},\n",
    "    config={\"configurable\": {\"session_id\": \"345\"}},\n",
    ")\n",
    "\n",
    "print(response)"
   ],
   "id": "7ce1de8583f8bdc6",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m我不知道你的名字。如果你愿意，可以告诉我你的名字。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'input': '我的名字叫什么？', 'chat_history': [], 'output': '我不知道你的名字。如果你愿意，可以告诉我你的名字。'}\n"
     ]
    }
   ],
   "execution_count": 14
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
